<html><head><meta charset="utf-8"><title>05 基础概念和常见配置项介绍（一）-慕课专栏</title>
			<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
			<meta name="renderer" content="webkit">
			<meta property="qc:admins" content="77103107776157736375">
			<meta property="wb:webmaster" content="c4f857219bfae3cb">
			<meta http-equiv="Access-Control-Allow-Origin" content="*">
			<meta http-equiv="Cache-Control" content="no-transform ">
			<meta http-equiv="Cache-Control" content="no-siteapp">
			<link rel="apple-touch-icon" sizes="76x76" href="https://www.imooc.com/static/img/common/touch-icon-ipad.png">
			<link rel="apple-touch-icon" sizes="120x120" href="https://www.imooc.com/static/img/common/touch-icon-iphone-retina.png">
			<link rel="apple-touch-icon" sizes="152x152" href="https://www.imooc.com/static/img/common/touch-icon-ipad-retina.png">
			<link href="https://moco.imooc.com/captcha/style/captcha.min.css" rel="stylesheet">
			<link rel="stylesheet" href="https://www.imooc.com/static/moco/v1.0/dist/css/moco.min.css?t=201907021539" type="text/css">
			<link rel="stylesheet" href="https://www.imooc.com/static/lib/swiper/swiper-3.4.2.min.css?t=201907021539">
			<link rel="stylesheet" href="https://static.mukewang.com/static/css/??base.css,common/common-less.css?t=2.5,column/zhuanlanChapter-less.css?t=2.5,course/inc/course_tipoff-less.css?t=2.5?v=201907051055" type="text/css">
			<link charset="utf-8" rel="stylesheet" href="https://www.imooc.com/static/lib/ueditor/themes/imooc/css/ueditor.css?v=201907021539"><link rel="stylesheet" href="https://www.imooc.com/static/lib/baiduShare/api/css/share_style0_16.css?v=6aba13f0.css"></head>
			<body><div id="main">

<div class="container clearfix" id="top" style="display: block; width: 1134px;">
    
    <div class="center_con js-center_con l" style="width: 1134px;">
        <div class="article-con">
                            <!-- 买过的阅读 -->
                <div class="map">
                    <a href="/read" target="_blank"><i class="imv2-feather-o"></i></a>
                    <a href="/read/29" target="_blank">Webpack 从零入门到工程化实战</a>
                    <a href="" target="_blank">
                        <span>
                            / 1-5 05 基础概念和常见配置项介绍（一）
                        </span>
                    </a>
                </div>

            


            <div class="art-title" style="margin-top: 0px;">
                05 基础概念和常见配置项介绍（一）
            </div>
            <div class="art-info">
                
                <span>
                    更新时间：2019-06-21 09:49:29
                </span>
            </div>
            <div class="art-top">
                                <img src="https://img1.mukewang.com/5cd962fd000101b306400360.jpg" alt="">
                                                <div class="famous-word-box">
                    <img src="https://www.imooc.com/static/img/column/bg-l.png" alt="" class="bg1 bg">
                    <img src="https://www.imooc.com/static/img/column/bg-r.png" alt="" class="bg2 bg">
                    <div class="famous-word">人生太短，要干的事太多，我要争分夺秒。<p class="author">——爱迪生</p></div>
                </div>
                            </div>
            <div class="art-content js-lookimg">
                <div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">本节介绍下跟 Webpack 配置相关的概念，以及介绍一个简单并且常用的配置项。</p>
</div><div class="cl-preview-section"><h2 id="webpack.config.js-配置文件" style="font-size: 30px;">webpack.config.js 配置文件</h2>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">Webpack 是可配置的模块打包工具，我们可以通过修改 Webpack 的配置文件（<code>webpack.config.js</code>）来对 Webpack 进行配置，Webpack 的配置文件是遵循 Node.js 的 CommonJS 模块规范的，即：</p>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;">通过<code>require()</code>语法导入其他文件或者使用 Node.js 内置的模块</li>
<li style="font-size: 20px; line-height: 38px;">普通的 JavaScript 编写语法，包括变量、函数、表达式等</li>
</ul>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">说白了，<code>webpack.config.js</code>是一个 Node.js 的模块。</p>
</div><div class="cl-preview-section"><h3 id="简单的-webpack.config.js-示例">简单的 webpack.config.js 示例</h3>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js"><span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'path'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    mode<span class="token punctuation">:</span> <span class="token string">'development'</span><span class="token punctuation">,</span>
    entry<span class="token punctuation">:</span> <span class="token string">'./foo.js'</span><span class="token punctuation">,</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        path<span class="token punctuation">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'dist'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'foo.bundle.js'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">上面示例中，使用 CommonJS 的<code>require</code>引入 Node.js 内置的<code>path</code>模块，然后通过<code>module.exports</code>将 Webpack 的配置导出。</p>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">Tips：Webpack 的配置是一个 Node.js 模块，所以并不只是 JSON 对象。</p>
</blockquote>
</div><div class="cl-preview-section"><h2 id="webpack-配置支持多种语言" style="font-size: 30px;">Webpack 配置支持多种语言</h2>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">Webpack 不仅仅支持 js 配置，还支持 ts（TypeScript）、CoffeeScript 甚至 <a href="https://reactjs.org/docs/introducing-jsx.html">JSX</a> 语法的配置，不同语言其实核心配置项都不变，只不过语法不同而已，<strong>本专栏都是 JavaScript 语法的配置</strong>。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">除了配置文件的语法多样之外，对于配置的类型也是多样的，最常见的是直接作为一个对象来使用，除了使用对象，Webpack 还支持函数、Promise 和多配置数组。</p>
</div><div class="cl-preview-section"><h3 id="函数类型的-webpack-配置">函数类型的 Webpack 配置</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">如果我们只使用一个配置文件来区分生产环境（production）和开发环境（development），则可以使用函数类型的 Webpack 配置，函数类型的配置必须返回一个配置对象，如下面：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token punctuation">(</span>env<span class="token punctuation">,</span> argv<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
        mode<span class="token punctuation">:</span> env<span class="token punctuation">.</span>production <span class="token operator">?</span> <span class="token string">'production'</span> <span class="token punctuation">:</span> <span class="token string">'development'</span><span class="token punctuation">,</span>
        devtool<span class="token punctuation">:</span> env<span class="token punctuation">.</span>production <span class="token operator">?</span> <span class="token string">'source-maps'</span> <span class="token punctuation">:</span> <span class="token string">'eval'</span><span class="token punctuation">,</span>
        plugins<span class="token punctuation">:</span> <span class="token punctuation">[</span>
            <span class="token keyword">new</span> <span class="token class-name">TerserPlugin</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
                terserOptions<span class="token punctuation">:</span> <span class="token punctuation">{</span>
                    compress<span class="token punctuation">:</span> argv<span class="token punctuation">[</span><span class="token string">'optimize-minimize'</span><span class="token punctuation">]</span> <span class="token comment">// 只有传入 -p 或 --optimize-minimize</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">]</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">Webpack 配置函数接受两个参数<code>env</code>和<code>argv</code>：分别对应着环境对象和 Webpack-CLI 的命令行选项，例如上面代码中的<code>--optimize-minimize</code>。</p>
</div><div class="cl-preview-section"><h3 id="promise-类型的-webpack-配置">Promise 类型的 Webpack 配置</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">如果需要异步加载一些 Webpack 配置需要做的变量，那么可以使用 Promise 的方式来做 Webpack 的配置，具体方式如下：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
                entry<span class="token punctuation">:</span> <span class="token string">'./app.js'</span>
                <span class="token comment">/* ... */</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><h3 id="多配置数组">多配置数组</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">在一些特定的场景，我们可能需要一次打包多次，而多次打包中有一些通用的配置，这时候可以使用配置数组的方式，将两次以上的 Webpack 配置以数组的形式导出：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">[</span>
    <span class="token punctuation">{</span>
        mode<span class="token punctuation">:</span> <span class="token string">'production'</span>
        <span class="token comment">// 配置1</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">{</span>
        <span class="token comment">// 配置2</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><h3 id="配置的使用">配置的使用</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">默认情况下，Webpack 会查找执行目录下面的<code>webpack.config.js</code>作为配置，如果需要指定某个配置文件，可以使用下面的命令：</p>
</div><div class="cl-preview-section"><pre class="  language-sh"><code class="prism  language-sh">webpack --config webpack.config.js
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">如果 Webpack 不是全局安装，则可以在项目目录下实行：</p>
</div><div class="cl-preview-section"><pre class="  language-sh"><code class="prism  language-sh">node ./node_modules/webpack/bin/webpack --config webpack.config.js
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">或者使用<code>npx</code></p>
</div><div class="cl-preview-section"><pre class="  language-bash"><code class="prism  language-bash">npx webpack --config webpack.config.js
</code></pre>
</div><div class="cl-preview-section"><h2 id="webpack-常见名词解释" style="font-size: 30px;">Webpack 常见名词解释</h2>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">讲完 Webpack 配置文件，下面讲下配置文件中的配置项。当我们谈论 Webpack 的时候，往往会提到下面的名词：</p>
</div><div class="cl-preview-section"><div class="table-wrapper"><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>entry</code></td>
<td>项目入口</td>
</tr>
<tr>
<td><code>module</code></td>
<td>开发中每一个文件都可以看做 module，模块不局限于 js，也包含 css、图片等</td>
</tr>
<tr>
<td><code>chunk</code></td>
<td>代码块，一个 chunk 可以由多个模块组成</td>
</tr>
<tr>
<td><code>loader</code></td>
<td>模块转化器，模块的处理器，对模块进行转换处理</td>
</tr>
<tr>
<td><code>plugin</code></td>
<td>扩展插件，插件可以处理 chunk，也可以对最后的打包结果进行处理，可以完成 loader 完不成的任务</td>
</tr>
<tr>
<td><code>bundle</code></td>
<td>最终打包完成的文件，一般就是和 chunk 一一对应的关系，bundle 就是对 chunk 进行便意压缩打包等处理后的产出</td>
</tr>
</tbody>
</table>
</div></div><div class="cl-preview-section"><h2 id="mode-模式" style="font-size: 30px;">mode 模式</h2>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">Webpack4.0 开始引入了<code>mode</code>配置，通过配置<code>mode=development</code>或者<code>mode=production</code>来制定是开发环境打包，还是生产环境打包，比如生产环境代码需要压缩，图片需要优化，Webpack 默认<code>mode</code>是生产环境，即<code>mode=production</code>。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">除了在配置文件中设置<code>mode</code>：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    mode<span class="token punctuation">:</span> <span class="token string">'development'</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">还可以在命令行中设置<code>mode</code>：</p>
</div><div class="cl-preview-section"><pre class="  language-sh"><code class="prism  language-sh">npx webpack --config webpack.config.entry.js --mode development
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">下面的内容及其后续的章节内容，如没有声明，则以<code>development</code>方式来做演示，这样方便查看输出的结果。</p>
</div><div class="cl-preview-section"><h2 id="webpack-的入口（entry）和输出（output）" style="font-size: 30px;">Webpack 的入口（entry）和输出（output）</h2>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">通过前面的文章我们已经了解到：<strong>webpack 是一个模块打包工具，能够从一个需要处理的 JavaScript 文件开始，构建一个依赖关系图（dependency graph），该图映射到了项目中每个模块，然后将这个依赖关系图输出到一个或者多个 bundle 中</strong>。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">从上面文字的认识，可以轻易的得到 Webpack 的两个核心概念：<code>entry</code>和<code>output</code>，即入口和输出，Webpack 是从指定的入口文件（entry）开始，经过加工处理，最终按照<code>output</code>设定输出固定内容的 bundle；而这个加工处理的过程，就用到了<code>loader</code>和<code>plugin</code>两个工具；<code>loader</code>是源代码的处理器，<code>plugin</code>解决的是 <code>loader</code>处理不了的事情。今天重点介绍下<code>entry</code>和<code>output</code>，在后面文章在介绍<code>loader</code>和<code>plugin</code>。</p>
</div><div class="cl-preview-section"><h3 id="context">context</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">在介绍<code>entry</code>之前，介绍下<code>context</code>（上下文），<code>context</code>即项目打包的相对路径上下文，如果指定了<code>context="/User/test/webpack"</code>，那么我们设置的<code>entry</code>和<code>output</code>的相对路径都是相对于<code>/User/test/webpack</code>的，包括在 JavaScript 中引入模块也是从这个路径开始的。由于<code>context</code>的作用，<strong>决定了<code>context</code>值必须是一个绝对路径</strong>。</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js"><span class="token comment">// webpack.config.js</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    context<span class="token punctuation">:</span> <span class="token string">'/Users/test/webpack'</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">Tips：在实际开发中 <code>context</code> 一般不需要配置，不配置则默认为<code>process.cwd()</code>即工作目录。<br>
工作目录（英语：Working directory），计算机用语。使用者在作业系统内所在的目录，使用者可在此用相对档名存取档案 —— 维基百科。</p>
</blockquote>
</div><div class="cl-preview-section"><h3 id="entry入口">entry入口</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">Webpack 的<code>entry</code>支持多种类型，包括字符串、对象、数组。从作用上来说，包括了<strong>单文件入口</strong>和<strong>多文件入口</strong>两种方式。</p>
</div><div class="cl-preview-section"><h4 id="单文件入口" style="font-size: 26px;">单文件入口</h4>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">单文件的用法如下：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    entry<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/file.js'</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// 或者使用对象方式</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    entry<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        main<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/file.js'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">单文件入口可以快速创建一个只有单一文件入口的情况，例如 library 的封装，但是单文件入口的方式相对来说比较简单，在扩展配置的时候灵活性较低。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><code>entry</code>还可以传入包含文件路径的数组，当<code>entry</code>为数组的时候也会合并输出，例如下面的配置：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    mode<span class="token punctuation">:</span> <span class="token string">'development'</span><span class="token punctuation">,</span>
    entry<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'./src/app.js'</span><span class="token punctuation">,</span> <span class="token string">'./src/home.js'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        filename<span class="token punctuation">:</span> <span class="token string">'array.js'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">Tips：上面配置无论是字符串还是字符串数组的 entry，实际上都是只有一个入口，但是在打包产出上会有差异：</p>
<p style="font-size: 20px; line-height: 38px;">1.如果直接是 string 的形式，那么 webpack 就会直接把该 string 指定的模块（文件）作为入口模块<br>
2.如果是数组 <code>[string]</code> 的形式，那么 webpack 会自动生成另外一个入口模块，并将数组中每个元素指定的模块（文件）加载进来，并将最后一个模块的 module.exports 作为入口模块的 module.exports 导出。<strong>这部分会在「原理篇：打包产出小节」继续做详细介绍</strong>。</p>
</blockquote>
</div><div class="cl-preview-section"><h4 id="多文件入口" style="font-size: 26px;">多文件入口</h4>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">多文件入口是使用对象语法来通过支持多个<code>entry</code>，多文件入口的对象语法相对于单文件入口，具有较高的灵活性，例如多页应用、页面模块分离优化。多文件入口的语法如下：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    entry<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        home<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/home.js'</span><span class="token punctuation">,</span>
        search<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/search.js'</span><span class="token punctuation">,</span>
        list<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/list.js'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">上面的语法将<code>entry</code>分成了 3 个独立的入口文件，这样会打包出来三个对应的 bundle，在后面的文章还会介绍使用<code>splitChunks</code>抽离一个项目中多个<code>entry</code>的公共代码。</p>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">Tips：对于一个 HTML 页面，我们推荐只有一个 <code>entry</code> ，通过统一的入口，解析出来的依赖关系更方便管理和维护。</p>
</blockquote>
</div><div class="cl-preview-section"><h3 id="output-输出">output 输出</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">webpack 的<code>output</code>是指定了<code>entry</code>对应文件编译打包后的输出 bundle。<code>output</code>的常用属性是：</p>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;"><code>path</code>：此选项制定了输出的 bundle 存放的路径，比如<code>dist</code>、<code>output</code>等</li>
<li style="font-size: 20px; line-height: 38px;"><code>filename</code>：这个是 bundle 的名称</li>
<li style="font-size: 20px; line-height: 38px;"><code>publicPath</code>：指定了一个在浏览器中被引用的 URL 地址，后面详细介绍</li>
</ul>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">后面章节还会继续介绍不同项目的<code>output</code>其他属性，比如我们要使用 webpack 作为库的封装工具，会用到<code>library</code>和<code>libraryTarget</code>等。</p>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">Tips：当不指定 output 的时候，默认输出到 <code>dist/main.js</code> ，即  <code>output.path</code> 是<code>dist</code>，<code>output.filename</code>  是 <code>main</code>。</p>
</blockquote>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">一个 webpack 的配置，<strong>可以包含多个<code>entry</code>，但是只能有一个<code>output</code></strong>。对于不同的<code>entry</code>可以通过<code>output.filename</code>占位符语法来区分，比如：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    entry<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        home<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/home.js'</span><span class="token punctuation">,</span>
        search<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/search.js'</span><span class="token punctuation">,</span>
        list<span class="token punctuation">:</span> <span class="token string">'path/to/my/entry/list.js'</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        filename<span class="token punctuation">:</span> <span class="token string">'[name].js'</span><span class="token punctuation">,</span>
        path<span class="token punctuation">:</span> __dirname <span class="token operator">+</span> <span class="token string">'/dist'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">其中<code>[name]</code>就是占位符，它对应的是<code>entry</code>的<code>key</code>（<code>home</code>、<code>search</code>、<code>list</code>），所以最终输出结果是：</p>
</div><div class="cl-preview-section"><pre><code>path/to/my/entry/home.js → dist/home.js
path/to/my/entry/search.js → dist/search.js
path/to/my/entry/list.js → dist/list.js
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">我将 Webpack 目前支持的占位符列出来：</p>
</div><div class="cl-preview-section"><div class="table-wrapper"><table>
<thead>
<tr>
<th>占位符</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>[hash]</code></td>
<td>模块标识符的 hash</td>
</tr>
<tr>
<td><code>[chunkhash]</code></td>
<td>chunk 内容的 hash</td>
</tr>
<tr>
<td><code>[name]</code></td>
<td>模块名称</td>
</tr>
<tr>
<td><code>[id]</code></td>
<td>模块标识符</td>
</tr>
<tr>
<td><code>[query]</code></td>
<td>模块的 query，例如，文件名 ? 后面的字符串</td>
</tr>
<tr>
<td><code>[function]</code></td>
<td>一个 return 出一个 string 作为 filename 的函数</td>
</tr>
</tbody>
</table>
</div></div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><code>[hash]</code> 和 <code>[chunkhash]</code> 的长度可以使用 <code>[hash:16]</code>（默认为 <strong>20</strong>）来指定。或者，通过指定 <code>output.hashDigestLength</code> 在全局配置长度，那么他们之间有什么区别吗？</p>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;"><code>[hash]</code>：是<strong>整个项目</strong>的 hash 值，其根据每次编译内容计算得到，每次编译之后都会生成新的 hash，即修改任何文件都会导致所有文件的 hash 发生改变；在一个项目中虽然入口不同，但是 hash 是相同的；hash 无法实现前端静态资源在浏览器上长缓存，这时候应该使用 chunkhash；</li>
<li style="font-size: 20px; line-height: 38px;"><code>[chunkhash]</code>：根据不同的入口文件（entry）进行依赖文件解析，构建对应的 chunk，生成相应的 hash；只要组成 entry 的模块文件没有变化，则对应的 hash 也是不变的，所以一般项目优化时，会将公共库代码拆分到一起，因为公共库代码变动较少的，使用 chunkhash 可以发挥最长缓存的作用；</li>
<li style="font-size: 20px; line-height: 38px;"><code>[contenthash]</code>：使用 chunkhash 存在一个问题，当在一个 JS 文件中引入了 CSS 文件，编译后它们的 hash 是相同的。而且，只要 JS 文件内容发生改变，与其关联的 CSS 文件 hash 也会改变，针对这种情况，可以把 CSS 从 JS 中使用<a href="https://github.com/webpack-contrib/mini-css-extract-plugin">mini-css-extract-plugin</a> 或 <a href="https://github.com/webpack-contrib/extract-text-webpack-plugin">extract-text-webpack-plugin</a>抽离出来并使用 contenthash。</li>
</ul>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><code>[hash]</code>、<code>[chunkhash]</code>和<code>[contenthash]</code>都支持<code>[xxx:length]</code>的语法。</p>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">Tips: 占位符是可以组合使用的，例如<code>[name]-[hash:8]</code></p>
</blockquote>
</div><div class="cl-preview-section"><h4 id="output.publicpath" style="font-size: 26px;">output.publicPath</h4>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">对于使用<code>&lt;script&gt;</code> 和 <code>&lt;link&gt;</code>标签时，当文件路径不同于他们的本地磁盘路径（由<code>output.path</code>指定）时，<code>output.publicPath</code>被用来作为<code>src</code>或者<code>link</code>指向该文件。这种做法在需要将静态文件放在不同的域名或者 CDN 上面的时候是很有用的。</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        path<span class="token punctuation">:</span> <span class="token string">'/home/git/public/assets'</span><span class="token punctuation">,</span>
        publicPath<span class="token punctuation">:</span> <span class="token string">'/assets/'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">则输出：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/assets/logo.png<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">上面的<code>/assets/logo.png</code>就是根据<code>publicPath</code>输出的，<code>output.path</code>制定了输出到本地磁盘的路径，而<code>output.publicPath</code>则作为实际上线到服务器之后的 url 地址。所以我们在上 CDN 的时候可以这样配置：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        path<span class="token punctuation">:</span> <span class="token string">'/home/git/public/assets'</span><span class="token punctuation">,</span>
        publicPath<span class="token punctuation">:</span> <span class="token string">'http://cdn.example.com/assets/'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">则输出：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://cdn.example.com/assets/logo.png<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
</code></pre>
</div><div class="cl-preview-section"><h4 id="output.library" style="font-size: 26px;"><code>output.library</code></h4>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">如果我们打包的目的是生成一个供别人使用的库，那么可以使用<code>output.library</code>来指定库的名称，库的名称支持占位符和普通字符串：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span> <span class="token comment">// '[name]'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><h4 id="output.librarytarget" style="font-size: 26px;"><code>output.libraryTarget</code></h4>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">使用<code>output.library</code> 确定了库的名称之后，还可以使用<code>output.libraryTarget</code>指定库打包出来的规范，<code>output.libraryTarget</code>取值范围为：<code>var</code>、<code>assign</code>、<code>this</code>、<code>window</code>、<code>global</code>、<code>commonjs</code>、<code>commonjs2</code>、<code>commonjs-module</code>、<code>amd</code>、<code>umd</code>、<code>umd2</code>、<code>jsonp</code>，默认是<code>var</code>，下面通过打包后的代码不同，来看下差别。</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js"><span class="token comment">// var config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'var.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'var'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
<span class="token keyword">var</span> myLib <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// assign config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'assign.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'assign'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output： 少了个 var</span>
 myLib <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// this config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'this.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'this'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
<span class="token keyword">this</span><span class="token punctuation">[</span><span class="token string">"myLib"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// window config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'window.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'window'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
window<span class="token punctuation">[</span><span class="token string">"myLib"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// ===============================================</span>
<span class="token comment">// global config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'global.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'global'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output：注意 target=node 的时候才是 global，默认 target=web下global 为 window</span>
window<span class="token punctuation">[</span><span class="token string">"myLib"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// commonjs config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'commonjs.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'commonjs'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
exports<span class="token punctuation">[</span><span class="token string">"myLib"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// amd config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'amd.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'amd'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
<span class="token function">define</span><span class="token punctuation">(</span><span class="token string">'myLib'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
        <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// ===============================================</span>
<span class="token comment">// umd config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'umd.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'umd'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">webpackUniversalModuleDefinition</span><span class="token punctuation">(</span>root<span class="token punctuation">,</span> factory<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> exports <span class="token operator">===</span> <span class="token string">'object'</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">typeof</span> module <span class="token operator">===</span> <span class="token string">'object'</span><span class="token punctuation">)</span> module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> define <span class="token operator">===</span> <span class="token string">'function'</span> <span class="token operator">&amp;&amp;</span> define<span class="token punctuation">.</span>amd<span class="token punctuation">)</span> <span class="token function">define</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> factory<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> exports <span class="token operator">===</span> <span class="token string">'object'</span><span class="token punctuation">)</span> exports<span class="token punctuation">[</span><span class="token string">'myLib'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> root<span class="token punctuation">[</span><span class="token string">'myLib'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>window<span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
        <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// commonjs2 config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'commonjs2.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'commonjs2'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// umd2 config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'umd2.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'umd2'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
<span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">webpackUniversalModuleDefinition</span><span class="token punctuation">(</span>root<span class="token punctuation">,</span> factory<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> exports <span class="token operator">===</span> <span class="token string">'object'</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">typeof</span> module <span class="token operator">===</span> <span class="token string">'object'</span><span class="token punctuation">)</span> module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> define <span class="token operator">===</span> <span class="token string">'function'</span> <span class="token operator">&amp;&amp;</span> define<span class="token punctuation">.</span>amd<span class="token punctuation">)</span> <span class="token function">define</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> factory<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> exports <span class="token operator">===</span> <span class="token string">'object'</span><span class="token punctuation">)</span> exports<span class="token punctuation">[</span><span class="token string">'myLib'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> root<span class="token punctuation">[</span><span class="token string">'myLib'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>window<span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
        <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// commonjs-module config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'commonjs-module.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'commonjs-module'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// output</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ===============================================</span>
<span class="token comment">// jsonp config</span>
<span class="token punctuation">{</span>
    output<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        library<span class="token punctuation">:</span> <span class="token string">'myLib'</span><span class="token punctuation">,</span>
        filename<span class="token punctuation">:</span> <span class="token string">'jsonp.js'</span><span class="token punctuation">,</span>
        libraryTarget<span class="token punctuation">:</span> <span class="token string">'jsonp'</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// output</span>
<span class="token function">myLib</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token string">'./src/index.js'</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span>module<span class="token punctuation">,</span> exports<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">注意： <code>libraryTarget=global</code> 的时候，如果  <code>target=node</code>  才是 global，默认  <code>target=web</code>  下 global 为 window，保险起见可以使用 <code>this</code>。</p>
</blockquote>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">下面介绍下跟 output 输出相关的三个配置项：<code>externals</code>，<code>target</code> 和 <code>devtool</code></p>
</div><div class="cl-preview-section"><h3 id="externals">externals</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><code>externals</code>配置项用于去除输出的打包文件中依赖的某些第三方 js 模块（例如 <code>jquery</code>，<code>vue</code> 等等），减小打包文件的体积。该功能通常在开发自定义 js 库（library）的时候用到，用于去除自定义 js 库依赖的其他第三方 js 模块。这些被依赖的模块应该由使用者提供，而不应该包含在 js 库文件中。例如开发一个 jQuery 插件或者 Vue 扩展，不需要把 jQuery 和 Vue 打包进我们的 bundle，引入库的方式应该交给使用者。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">所以，这里就有个重要的问题，使用者应该怎么提供这些被依赖的模块给我们的 js 库（library）使用呢？这就要看我们的 js 库的导出方式是什么，以及使用者采用什么样的方式使用我们的库。例如：</p>
</div><div class="cl-preview-section"><div class="table-wrapper"><table>
<thead>
<tr>
<th>js library 导出方式</th>
<th>output.libraryTarget</th>
<th>使用者引入方式</th>
<th>使用者提供给被依赖模块的方式</th>
</tr>
</thead>
<tbody>
<tr>
<td>默认的导出方式</td>
<td>output.libraryTarget=‘var’</td>
<td><strong>只能</strong>以 <code>&lt;script&gt;</code> 标签的形式引入我们的库</td>
<td><strong>只能以全局变量</strong>的形式提供这些被依赖的模块</td>
</tr>
<tr>
<td>commonjs</td>
<td>output.libraryTarget=‘commonjs’</td>
<td><strong>只能</strong>按照 commonjs 的规范引入我们的库</td>
<td>被依赖模块需要按照 commonjs 规范引入</td>
</tr>
<tr>
<td>amd</td>
<td>output.libraryTarget=‘amd’</td>
<td>只能按照 amd 规范引入</td>
<td>被依赖模块需要按照 amd 规范引入</td>
</tr>
<tr>
<td>umd</td>
<td>output.libraryTarget=‘umd’</td>
<td>可以用<code>&lt;script&gt;</code>、commonjs、amd 引入</td>
<td>被依赖模块需要按照对应方式引入</td>
</tr>
</tbody>
</table>
</div></div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">如果不是在开发一个 js 库，即没有设置 <code>output.library</code>, <code>output.libraryTarget</code> 等配置信息，那么我们生成的打包文件只能以 <code>&lt;script&gt;</code> 标签的方式在页面中引入，因此那些被去除的依赖模块也只能以全局变量的方式引入。</p>
</div><div class="cl-preview-section"><h3 id="target">target</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">在项目开发中，我们不仅仅是开发 web 应用，还可能开发的是 Node.js 服务应用、或者 electron 这类跨平台桌面应用，这时候因为对应的宿主环境不同，所以在构建的时候需要特殊处理。webpack 中可以通过设置<code>target</code>来指定构建的目标（target）。</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
    target<span class="token punctuation">:</span> <span class="token string">'web'</span> <span class="token comment">// 默认是 web，可以省略</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><code>target</code>的值有两种类型：string 和 function。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><code>string</code> 类型支持下面的七种：</p>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;"><code>web</code>：<strong>默认</strong>，编译为类浏览器环境里可用；</li>
<li style="font-size: 20px; line-height: 38px;"><code>node</code>：编译为类 Node.js 环境可用（使用 Node.js require 加载 chunk）；</li>
<li style="font-size: 20px; line-height: 38px;"><code>async-node</code>：编译为类 Node.js 环境可用（使用 fs 和 vm 异步加载分块）；</li>
<li style="font-size: 20px; line-height: 38px;"><code>electron-main</code>：编译为 Electron 主进程；</li>
<li style="font-size: 20px; line-height: 38px;"><code>electron-renderer</code>：编译为 Electron 渲染进程；</li>
<li style="font-size: 20px; line-height: 38px;"><code>node-webkit</code>：编译为 Webkit 可用，并且使用 jsonp 去加载分块。支持 Node.js 内置模块和 nw.gui 导入（<strong>实验性质</strong>）；</li>
<li style="font-size: 20px; line-height: 38px;"><code>webworker</code>：编译成一个 WebWorker。</li>
</ul>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">后面章节介绍 webpack 特殊项目类型配置的时候还会介绍 <code>target</code> 相关的用法。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">除了<code>string</code>类型，target 还支持 <code>function</code> 类型，这个函数接收一个<code>compiler</code>作为参数，如下面代码可以用来增加插件：</p>
</div><div class="cl-preview-section"><pre class="  language-js"><code class="prism  language-js"><span class="token keyword">const</span> webpack <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'webpack'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> options <span class="token operator">=</span> <span class="token punctuation">{</span>
    target<span class="token punctuation">:</span> compiler <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        compiler<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">webpack<span class="token punctuation">.</span>JsonpTemplatePlugin</span><span class="token punctuation">(</span>options<span class="token punctuation">.</span>output<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">webpack<span class="token punctuation">.</span>LoaderTargetPlugin</span><span class="token punctuation">(</span><span class="token string">'web'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><h3 id="devtool">devtool</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><code>devtool</code>是来控制怎么显示<a href="http://blog.teamtreehouse.com/introduction-source-maps">sourcemap</a>，通过 sourcemap 我们可以快速还原代码的错误位置。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">但是由于 sourcemap 包含的数据量较大，而且生成算法需要计算量支持，所以 sourcemap 的生成会消耗打包的时间，下面的表格整理了不同的<code>devtool</code>值对应不同的 sourcemap 类型对应打包速度和特点。</p>
</div><div class="cl-preview-section"><div class="table-wrapper"><table>
<thead>
<tr>
<th>devtool</th>
<th>构建速度</th>
<th>重新构建速度</th>
<th>生产环境</th>
<th>品质(quality)</th>
</tr>
</thead>
<tbody>
<tr>
<td>留空，none</td>
<td>+++</td>
<td>+++</td>
<td>yes</td>
<td>打包后的代码</td>
</tr>
<tr>
<td>eval</td>
<td>+++</td>
<td>+++</td>
<td>no</td>
<td>生成后的代码</td>
</tr>
<tr>
<td>cheap-eval-source-map</td>
<td>+</td>
<td>++</td>
<td>no</td>
<td>转换过的代码（仅限行）</td>
</tr>
<tr>
<td>cheap-module-eval-source-map</td>
<td>o</td>
<td>++</td>
<td>no</td>
<td>原始源代码（仅限行）</td>
</tr>
<tr>
<td>eval-source-map</td>
<td>–</td>
<td>+</td>
<td>no</td>
<td>原始源代码</td>
</tr>
<tr>
<td>cheap-source-map</td>
<td>+</td>
<td>o</td>
<td>no</td>
<td>转换过的代码（仅限行）</td>
</tr>
<tr>
<td>cheap-module-source-map</td>
<td>o</td>
<td>-</td>
<td>no</td>
<td>原始源代码（仅限行）</td>
</tr>
<tr>
<td>inline-cheap-source-map</td>
<td>+</td>
<td>o</td>
<td>no</td>
<td>转换过的代码（仅限行）</td>
</tr>
<tr>
<td>inline-cheap-module-source-map</td>
<td>o</td>
<td>-</td>
<td>no</td>
<td>原始源代码（仅限行）</td>
</tr>
<tr>
<td>source-map</td>
<td>–</td>
<td>–</td>
<td>yes</td>
<td>原始源代码</td>
</tr>
<tr>
<td>inline-source-map</td>
<td>–</td>
<td>–</td>
<td>no</td>
<td>原始源代码</td>
</tr>
<tr>
<td>hidden-source-map</td>
<td>–</td>
<td>–</td>
<td>yes</td>
<td>原始源代码</td>
</tr>
<tr>
<td>nosources-source-map</td>
<td>–</td>
<td>–</td>
<td>yes</td>
<td>无源代码内容</td>
</tr>
</tbody>
</table>
</div></div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;"><code>+++</code> 非常快速, <code>++</code> 快速, <code>+</code> 比较快, <code>o</code> 中等, <code>-</code> 比较慢, <code>--</code> 慢</p>
</blockquote>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><strong>一般在实际项目中，我个人推荐生产环境不使用或者使用 source-map（如果有 <a href="https://sentry.io/">Sentry</a> 这类错误跟踪系统），开发环境使用<code>cheap-module-eval-source-map</code>。</strong></p>
</div><div class="cl-preview-section"><div class="summary"><h5 class="centertitle" style="font-size: 20px; line-height: 38px;">小结 </h5></div><!--title:&#23567;&#32467; -->
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">本小节从 webpack 的配置文件<code>webpack.config.js</code>基本语法开始，分别介绍了配置的基本用法，<code>mode</code>、<code>context</code>、<code>entry</code>、<code>output</code>、<code>target</code>等 webpack 中的基础概念。希望大家读完本小节内容之后，能够动手实际操作一下。在记忆方面，可以</p>
</div><div class="cl-preview-section"><blockquote>
<p style="font-size: 20px; line-height: 38px;">本小节 Webpack 相关面试题：</p>
<ol>
<li style="font-size: 20px; line-height: 38px;">Webpack 的配置有几种写法，分别可以应用到什么场景？</li>
<li style="font-size: 20px; line-height: 38px;">我们要开发一个 jQuery 插件、Vue 组件等，需要怎么配置 Webpack？</li>
<li style="font-size: 20px; line-height: 38px;">Webpack 的占位符 <code>[hash]</code> 、<code>[chunkhash]</code> 和 <code>[contenthash]</code> 有什么区别和联系？最佳实践是什么？</li>
<li style="font-size: 20px; line-height: 38px;">Webpack 的 SourceMap 有几种形式？分别有什么特点？SourceMap 配置的最佳实践是什么？</li>
<li style="font-size: 20px; line-height: 38px;">什么是  bundle ，什么是 chunk，什么是 module？</li>
</ol>
</blockquote>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">专栏代码已经整理好给大家共享出来：<br>
<a href="https://github.com/ksky521/webpack-tutorial">https://github.com/ksky521/webpack-tutorial</a></p>
</div></div>
            </div>
                            <!-- 买过的阅读 -->
                <div class="art-next-prev clearfix">
                                                                        <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/29/article/262">
                                                    <div class="prev l clearfix">
                                <div class="icon l">
                                    <i class="imv2-arrow3_l"></i>
                                </div>
                                <p>
                                    04 使用 webpack-cli 体验零配置打包
                                </p>
                            </div>
                        </a>
                                                                                            <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/29/article/264">
                                                    <div class="next r clearfix">
                                <p>
                                    06 基础概念和常见配置项介绍（二）
                                </p>
                                <div class="icon r">
                                    <i class="imv2-arrow3_r"></i>
                                </div>

                            </div>
                        </a>
                                    </div>
                    </div>
        <div class="comments-con js-comments-con" id="coments_con">
        </div>



    </div>
    
    
    

</div>
 
<!-- 专栏介绍页专栏评价 -->

<!-- 专栏介绍页底部三条评价 -->

<!-- 专栏阅读页弹层目录和介绍页页面目录 -->

<!-- 专栏阅读页发布回复 -->

<!-- 专栏阅读页发布评论 -->

<!-- 专栏阅读页底部评论 -->

<!-- 专栏阅读 单个 评论 -->

<!-- 新增回复和展开三条以外回复 -->

<!-- 立即订阅的弹窗 -->












</div></body></html>